package com.wangsh.userscenter.head.controller;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSONObject;
import com.wangsh.userscenter.common.controller.BaseController;
import com.wangsh.userscenter.common.util.ConstatFinalUtil;
import com.wangsh.userscenter.common.util.EncryptUtil;
import com.wangsh.userscenter.service.users.api.IUsersService;
import com.wangsh.userscenter.service.users.pojo.AUsers;
import com.wangsh.userscenter.service.users.pojo.AUsersEnum;
import com.wangsh.userscenter.service.users.pojo.AUsersExtend;
import com.wangsh.userscenter.util.ServiceCallableUtil;

/**
 * 未登陆页面
 * @author wangsh_sxt
 *
 */
@Controller
public class NoLoginController extends BaseController
{
	@Autowired
	private IUsersService usersService ;
	/**
	 * 登陆
	 * @return
	 */
	/**
	 * @param request
	 * @return
	 * @throws IOException 
	 */
	@RequestMapping("/login.html")
	public String login(HttpServletRequest request,HttpServletResponse response) throws IOException
	{
		this.clearInfo(request);
		/* 接收页面参数 */
		String returnUrl = request.getParameter("returnUrl");
		if(returnUrl == null)
		{
			returnUrl = ""; 
		}
		AUsers users = (AUsers) this.findObjfromSession(request, "1");
		if(users != null)
		{
			/* 登陆成功处理页面跳转 */
			if(logSuccedReturnUrl(response, returnUrl, users))
			{
				return null ; 
			}
			/* 用户已经登陆 */
			return "redirect:/head/users/main.html" ; 
		}
		returnUrl = URLEncoder.encode(returnUrl, "UTF-8");
		request.setAttribute("returnUrl", returnUrl);
		return "/login"; 
	}
	
	/**
	 * 登陆提交
	 * @return
	 * @throws IOException 
	 */
	@RequestMapping("/loginSubmit.html")
	public String loginSubmit(HttpServletRequest request,HttpServletResponse response) throws IOException
	{
		HttpSession session = request.getSession();
		/* 接收参数 */
		String email = request.getParameter("email");
		String password = request.getParameter("password");
		String code = request.getParameter("code");
		/* 登陆成功跳转的URL */
		String returnUrl = request.getParameter("returnUrl");
		
		/*图片验证码验证*/
		String randSess = session.getAttribute("randSess") + "";
		
		/* 移除验证码,防止重复使用 */
		session.removeAttribute("randSess");
		
		/* 验证码相同 */
		if(randSess.equalsIgnoreCase(code))
		{
			/* 查询db,处理业务逻辑 */
			Map<String, Object> condMap = new HashMap<String, Object>();
			condMap.put("email", email);
			AUsers users = this.usersService.findOneUsersService(condMap);
			/* 检验邮箱 */
			if(users != null)
			{
				/* 检验密码 */
				if(EncryptUtil.checkPassword(password, users.getPassword()))
				{
					/* 校验状态 */
					if(users.getStatus() == 1)
					{
						/* 登陆成功 */
						session.setAttribute("users", users);
						session.setAttribute("lastLoginTime", users.getLastLoginTime());
						
						/* 修改管理员操作 */
						users.setLoginCount(users.getLoginCount() + 1);
						users.setLastLoginTime(new Date());
						
						/* 不更新扩展信息 */
						users.setUsersExtend(null);
						this.usersService.updateOneUsersService(users);
						
						/* 登陆成功处理页面跳转 */
						if(logSuccedReturnUrl(response, returnUrl, users))
						{
							return null ; 
						}
						return "redirect:/head/users/main.html" ; 
					}else
					{
						this.info = "账户状态为:" + users.getStatusStr();
					}
				}else
				{
					this.info = "密码不正确" ; 
				}
				request.setAttribute("users", users);
			}else
			{
				this.info = "邮箱不存在" ; 
			}
		}else
		{
			this.info = "验证码不正确" ; 
		}
		request.setAttribute("returnUrl", returnUrl);
		request.setAttribute("info", info);
		return "login";
	}
	
	/**
	 * 单点登陆,returnUrl处理
	 * @param response
	 * @param returnUrl
	 * @param users
	 * @return
	 * @throws IOException
	 */
	private boolean logSuccedReturnUrl(HttpServletResponse response, String returnUrl, AUsers users) throws IOException
	{
		if(returnUrl == null)
		{
			returnUrl = ""; 
		}
		returnUrl = URLDecoder.decode(returnUrl, "UTF-8");
		String ticket = UUID.randomUUID().toString() ; 
		users.setTicketStr(ticket);
		this.usersService.addUsersTicketService(users);
		String ticketCond = "ticket=" + ticket ;
		String ticketIndex = "ticket=" ; 
		if(!"".equalsIgnoreCase(returnUrl))
		{
			/* 拼装处理returnUrl */
			if(returnUrl.indexOf(ticketIndex) != -1 )
			{
				String returnUrlStart = returnUrl.substring(0, returnUrl.indexOf(ticketIndex));
				String returnUrlEnd = returnUrl.substring(returnUrl.indexOf(ticketIndex) + ticketIndex.length(), returnUrl.length());
				if(returnUrlEnd.indexOf("&") != -1)
				{
					returnUrlEnd = returnUrlEnd.substring(returnUrlEnd.indexOf("&") + 1 , returnUrlEnd.length());
				}else
				{
					returnUrlEnd = "" ;
				}
				returnUrl = returnUrlStart + ticketCond + returnUrlEnd ; 
			}else if(returnUrl.indexOf("?") != -1)
			{
				/* 找到?,并且找到ticket */
				returnUrl += "&" + ticketCond ;
			}else
			{
				returnUrl += "?" + ticketCond ;
			}
		}
		
		/* 如果带了returnUrl,直接跳转returnUrl */
		if(!"".equalsIgnoreCase(returnUrl))
		{
			response.sendRedirect(returnUrl);
			return true ; 
		}
		return false ; 
	}
	
	/**
	 * 注册
	 * @return
	 */
	@RequestMapping("/regsiter.html")
	public String regsiter()
	{
		return "/regsiter"; 
	}
	
	/**
	 * 注册提交
	 * @return
	 */
	@RequestMapping("/regsiterSubmit.html")
	public String regsiterSubmit(HttpServletRequest request)
	{
		HttpSession session = request.getSession();
		/* 接收参数 */
		String email = request.getParameter("email");
		String password = request.getParameter("password");
		String code = request.getParameter("code");
		
		/*图片验证码验证*/
		String randSess = session.getAttribute("randSess") + "";
		
		/* 移除验证码,防止重复使用 */
		session.removeAttribute("randSess");
		
		/* 验证码相同 */
		if(randSess.equalsIgnoreCase(code))
		{
			AUsers users = new AUsers();
			users.setEmail(email);
			users.setPassword(EncryptUtil.encode(password));
			users.setStatus(AUsersEnum.STATUS_ENABLE.getStatus());
			users.setCreateTime(new Date());
			users.setUpdateTime(new Date());
			users.setLastLoginTime(new Date());
			JSONObject dbJSON = this.usersService.saveOneUsersService(users);
			if("0".equalsIgnoreCase(dbJSON.getString("code")))
			{
				info = "注册成功" ; 
				/* 发送注册邮件 */
				return this.emailVerfySend(request);
			}else 
			{
				info = dbJSON.getString("info") ; 
			}
		}else
		{
			info = "验证码不正确" ; 
		}
		request.setAttribute("info", info);
		return this.regsiter() ; 
	}
	
	/**
	 * 邮箱验证重新发送邮件
	 * @return
	 */
	@RequestMapping("/emailVerfySend.html")
	public String emailVerfySend(HttpServletRequest request)
	{
		HttpSession session = request.getSession();
		/* 根据邮箱来操作 */
		String email = request.getParameter("email");
		if(email == null)
		{
			email = "" ; 
		}
		
		if(!"".equalsIgnoreCase(email))
		{
			Map<String, Object> condMap = new HashMap<String,Object>();
			condMap.put("email", email);
			AUsers users = this.usersService.findOneUsersService(condMap);
			if(users != null)
			{
				if(users.getEmailStatus() != AUsersEnum.EMAILSTATUS_PASSED.getStatus())
				{
					AUsersExtend usersExtend = users.getUsersExtend(); 
					usersExtend.setSendEmailTime(new Date());
					/* 加密字符串:  db存储为:sha256(邮箱+时间,邮箱)*/
					String souStr = email + "_" + this.dateUtil.formatDateTime(usersExtend.getSendEmailTime()) ; 
					souStr = EncryptUtil.hmacSHA256(souStr, email);
					usersExtend.setSendEmailCode(souStr);
					
					/* 发送邮件 */
					Map<String, String> emailMap = new HashMap<String, String>();
					emailMap.put("date", this.dateUtil.formatDateTime(new Date()));
					/* 邮箱验证的url */
					emailMap.put("verifyHref", ConstatFinalUtil.SYS_BUNDLE.getString("website.url") + "/emailVerfy.html?code=" + 
							usersExtend.getSendEmailCode() + "&email=" + users.getEmail());
					emailMap.put("websiteurl", ConstatFinalUtil.SYS_BUNDLE.getString("website.url"));
					
					String subject = "邮箱认证 - 用户中心 " ; 
					emailMap.put("email", users.getEmail());
					emailMap.put("subject", subject);
					
					InputStream is = ConstatFinalUtil.class.getResourceAsStream("/template/email/emailVerify.html");
					String content = this.fileUtil.readFile(is, ConstatFinalUtil.CHARSET, emailMap);
					
					List<Callable<Integer>> callList = new ArrayList<Callable<Integer>>();
					Map<String, Object> paramsMap = new HashMap<String, Object>();
					
					paramsMap.put("springEmailUtil", springEmailUtil);
					paramsMap.put("email", emailMap.get("email") + "");
					paramsMap.put("subject", subject);
					paramsMap.put("content", content);
					
					ServiceCallableUtil multiThreadUtil = new ServiceCallableUtil();
					multiThreadUtil.setParamsMap(paramsMap);
					multiThreadUtil.setOperType("sendEmail");
					callList.add(multiThreadUtil);
					
					//固定设置线程数为
					ExecutorService exeSvc = Executors.newFixedThreadPool(callList.size());
					try
					{
						exeSvc.submit(multiThreadUtil);
					} catch (Exception e)
					{
						ConstatFinalUtil.SYS_LOG.error("线程池报错了", e);
					}finally
					{
						exeSvc.shutdown();
					}
					
					JSONObject dbJSON = this.usersService.updateOneUsersExtendService(usersExtend);
					ConstatFinalUtil.SYS_LOG.info("邮箱验证:发送邮件,db执行结果:{}",dbJSON);
					info = "邮件已经发送,请查收;<a href='"+ request.getContextPath() +"/emailVerfySend.html?email="+ email +"'>重新发送</a>" ; 
				}else
				{
					info = "邮箱已经认证" ;
				}
			}else 
			{
				info = "邮箱未注册"; 
			}
		}else
		{
			info = "邮箱不能为空" ; 
		}
		
		session.setAttribute("info", info);
		return "redirect:/commonInfo.html" ; 
	}
	
	/**
	 * 验证邮箱
	 * @param request
	 * @return
	 */
	@RequestMapping("/emailVerfy.html")
	public String emailVerfy(HttpServletRequest request)
	{
		HttpSession session = request.getSession() ;
		String email = request.getParameter("email");
		String code = request.getParameter("code");
		if(email == null)
		{
			email = "" ; 
		}
		
		if(!"".equalsIgnoreCase(email))
		{
			Map<String, Object> condMap = new HashMap<String,Object>();
			condMap.put("email", email);
			AUsers users = this.usersService.findOneUsersService(condMap);
			if(users != null)
			{
				boolean flag = true  ;
				AUsersExtend usersExtend = users.getUsersExtend();
				Calendar calendar = Calendar.getInstance();
				String souStr = email + "_" + this.dateUtil.formatDateTime(usersExtend.getSendEmailTime()) ; 
				String encodeCode = EncryptUtil.hmacSHA256(souStr, email);
				
				if((calendar.getTimeInMillis() - usersExtend.getSendEmailTime().getTime() > ConstatFinalUtil.SECOND * 60 * 60 * 24))
				{
					/* 验证邮箱时间 */
					info = "邮箱链接已经超过一天" ;
					flag = false ; 
				}else if(!encodeCode.equalsIgnoreCase(code))
				{
					/* 验证邮件的合法性 */
					info = "邮箱链接已经被篡改" ;
					flag = false; 
				}else if(users.getEmailStatus() == AUsersEnum.EMAILSTATUS_PASSED.getStatus())
				{
					/* 验证邮箱是否被验证过 */
					flag = false; 
					info = "邮箱已经认证" ;
				}
				
				if(flag)
				{
					usersExtend.setSendEmailTime(new Date());
					/* 加密字符串:  db存储为:sha256(邮箱+时间,邮箱)*/
					souStr = email + "_" + this.dateUtil.formatDateTime(usersExtend.getSendEmailTime()) ; 
					souStr = EncryptUtil.hmacSHA256(souStr, email);
					usersExtend.setSendEmailCode(souStr);
					
					/* 修改邮箱状态 */
					users.setEmailStatus(AUsersEnum.EMAILSTATUS_PASSED.getStatus());
					usersExtend.setUpdateTime(new Date());
					JSONObject dbJSON = this.usersService.updateOneUsersService(users);
					ConstatFinalUtil.SYS_LOG.info("邮箱验证结果:邮箱:{},db执行结果:{}" , email , dbJSON);
					info = "邮箱验证成功" ;
				}				
			}else 
			{
				info = "邮箱未注册"; 
			}
		}else
		{
			info = "邮箱不能为空" ; 
		}
		session.setAttribute("info", info);
		return "redirect:/commonInfo.html" ; 
	}
	
	/**
	 * 忘记密码
	 * @return
	 */
	@RequestMapping("/forgetPass.html")
	public String forgetPass(HttpServletRequest request)
	{
		return "/forgetPass" ; 
	}
	
	/**
	 * 忘记密码提交
	 * @return
	 */
	@RequestMapping("/forgetPassSubmit.html")
	public String forgetPassSubmit(HttpServletRequest request)
	{
		HttpSession session = request.getSession();
		/* 根据邮箱来操作 */
		String email = request.getParameter("email");
		if(email == null)
		{
			email = "" ; 
		}
		
		if(!"".equalsIgnoreCase(email))
		{
			String code = request.getParameter("code");
			
			/*图片验证码验证*/
			String randSess = session.getAttribute("randSess") + "";
			
			/* 移除验证码,防止重复使用 */
			session.removeAttribute("randSess");
			
			/* 验证码相同 */
			if(randSess.equalsIgnoreCase(code))
			{
				Map<String, Object> condMap = new HashMap<String,Object>();
				condMap.put("email", email);
				AUsers users = this.usersService.findOneUsersService(condMap);
				if(users != null)
				{
					AUsersExtend usersExtend = users.getUsersExtend(); 
					usersExtend.setSendEmailTime(new Date());
					/* 加密字符串:  db存储为:sha256(邮箱+时间,邮箱)*/
					String souStr = email + "_" + this.dateUtil.formatDateTime(usersExtend.getSendEmailTime()) ; 
					souStr = EncryptUtil.hmacSHA256(souStr, email);
					usersExtend.setSendEmailCode(souStr);
					
					/* 发送邮件 */
					Map<String, String> emailMap = new HashMap<String, String>();
					emailMap.put("date", this.dateUtil.formatDateTime(new Date()));
					/* 邮箱验证的url */
					emailMap.put("verifyHref", ConstatFinalUtil.SYS_BUNDLE.getString("website.url") + "/resetPass.html?code=" + 
							usersExtend.getSendEmailCode() + "&email=" + users.getEmail());
					emailMap.put("websiteurl", ConstatFinalUtil.SYS_BUNDLE.getString("website.url"));
					
					String subject = "重置密码 - 用户中心 " ; 
					emailMap.put("email", users.getEmail());
					emailMap.put("subject", subject);
					
					InputStream is = ConstatFinalUtil.class.getResourceAsStream("/template/email/resetPass.html");
					String content = this.fileUtil.readFile(is, ConstatFinalUtil.CHARSET, emailMap);
					
					List<Callable<Integer>> callList = new ArrayList<Callable<Integer>>();
					Map<String, Object> paramsMap = new HashMap<String, Object>();
					
					paramsMap.put("springEmailUtil", springEmailUtil);
					paramsMap.put("email", emailMap.get("email") + "");
					paramsMap.put("subject", subject);
					paramsMap.put("content", content);
					
					ServiceCallableUtil multiThreadUtil = new ServiceCallableUtil();
					multiThreadUtil.setParamsMap(paramsMap);
					multiThreadUtil.setOperType("sendEmail");
					callList.add(multiThreadUtil);
					
					//固定设置线程数为
					ExecutorService exeSvc = Executors.newFixedThreadPool(callList.size());
					try
					{
						exeSvc.submit(multiThreadUtil);
					} catch (Exception e)
					{
						ConstatFinalUtil.SYS_LOG.error("线程池报错了", e);
					}finally
					{
						exeSvc.shutdown();
					}
					
					JSONObject dbJSON = this.usersService.updateOneUsersExtendService(usersExtend);
					ConstatFinalUtil.SYS_LOG.info("忘记密码:发送邮件,db执行结果:{}",dbJSON);
					info = "邮件已经发送,请查收;<a href='"+ request.getContextPath() +"/emailVerfySend.html?email="+ email +"'>重新发送</a>" ; 
				}else
				{
					info = "验证码不正确" ;
				}
			}else 
			{
				info = "邮箱未注册"; 
			}
		}else
		{
			info = "邮箱不能为空" ; 
		}
		
		session.setAttribute("info", info);
		return this.forgetPass(request) ; 
	}
	
	/**
	 * 重置密码
	 * @return
	 */
	@RequestMapping("/resetPass.html")
	public String resetPass(HttpServletRequest request)
	{
		HttpSession session = request.getSession();
		/* 根据邮箱来操作 */
		String email = request.getParameter("email");
		String code = request.getParameter("code");
		if(email == null)
		{
			email = "" ; 
		}
		
		if(!"".equalsIgnoreCase(email))
		{
			Map<String, Object> condMap = new HashMap<String,Object>();
			condMap.put("email", email);
			AUsers users = this.usersService.findOneUsersService(condMap);
			if(users != null)
			{
				boolean flag = true  ;
				AUsersExtend usersExtend = users.getUsersExtend();
				Calendar calendar = Calendar.getInstance();
				String souStr = email + "_" + this.dateUtil.formatDateTime(usersExtend.getSendEmailTime()) ; 
				String encodeCode = EncryptUtil.hmacSHA256(souStr, email);
				
				if((calendar.getTimeInMillis() - usersExtend.getSendEmailTime().getTime() > ConstatFinalUtil.SECOND * 60 * 60 * 24))
				{
					/* 验证邮箱时间 */
					info = "邮箱链接已经超过一天" ;
					flag = false ; 
				}else if(!encodeCode.equalsIgnoreCase(code))
				{
					/* 验证邮件的合法性 */
					info = "邮箱链接已经被篡改" ;
					flag = false; 
				}
				
				if(flag)
				{
					info = ""; 
					request.setAttribute("info", info);
					request.setAttribute("users", users);
					//符合要求,跳转页面
					return "/resetPass" ; 
				}
			}else
			{
				info = "邮箱不存在" ; 
			}
		}else
		{
			info = "邮箱不能为空" ; 
		}
		
		session.setAttribute("info", info);
		return "redirect:/commonInfo.html" ; 
	}
	
	/**
	 * 重置密码提交
	 * @return
	 */
	@RequestMapping("/resetPassSubmit.html")
	public String resetPassSubmit(HttpServletRequest request)
	{
		HttpSession session = request.getSession();
		/* 根据邮箱来操作 */
		String email = request.getParameter("email");
		if(email == null)
		{
			email = "" ; 
		}
		
		if(!"".equalsIgnoreCase(email))
		{
			String code = request.getParameter("code");
			
			/*图片验证码验证*/
			String randSess = session.getAttribute("randSess") + "";
			
			/* 移除验证码,防止重复使用 */
			session.removeAttribute("randSess");
			
			/* 验证码相同 */
			if(randSess.equalsIgnoreCase(code))
			{
				Map<String, Object> condMap = new HashMap<String,Object>();
				condMap.put("email", email);
				AUsers users = this.usersService.findOneUsersService(condMap);
				if(users != null)
				{
					boolean flag = true  ;
					String password = request.getParameter("password");
					users.setPassword(EncryptUtil.encode(password));
					if(flag)
					{
						AUsersExtend usersExtend = users.getUsersExtend() ; 
						usersExtend.setSendEmailTime(new Date());
						/* 加密字符串:  db存储为:sha256(邮箱+时间,邮箱)*/
						String souStr = email + "_" + this.dateUtil.formatDateTime(usersExtend.getSendEmailTime()) ; 
						souStr = EncryptUtil.hmacSHA256(souStr, email);
						usersExtend.setSendEmailCode(souStr);
						usersExtend.setUpdateTime(new Date());
						this.usersService.updateOneUsersExtendService(usersExtend);
						
						users.setUpdateTime(new Date());
						JSONObject dbJSON = this.usersService.updateOneUsersService(users);
						ConstatFinalUtil.SYS_LOG.info("重置密码:邮箱:{},db结果:{}" , email , dbJSON);
						info = "密码重置成功" ;
					}
				}else 
				{
					info = "邮箱未注册"; 
				}
			}else
			{
				info = "验证码不正确" ; 
			}
		}else
		{
			info = "邮箱不能为空" ; 
		}
		
		session.setAttribute("info", info);
		return "redirect:/commonInfo.html" ; 
	}
}
